package org.fuxia.im.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextPane;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import org.fuxia.im.common.ClientContext;
import org.fuxia.im.common.FileTranferPanel;
import org.fuxia.im.core.ECMessageType;
import org.fuxia.im.core.entries.ECPacket;
import org.fuxia.im.core.socket.FileTransferCallBack;
import org.fuxia.im.core.socket.FileTransferSocketClient;
import org.fuxia.im.core.socket.impl.ECNioClient;
import org.fuxia.im.entities.User;
import org.fuxia.im.gui.util.FileUtil;
import org.tony.common.ui.CommonFrame;

public class Chat extends CommonFrame {

	private static final long serialVersionUID = 1L;
	private JPanel contentPane;
	private User user;
	private JPanel showPanel ;
	private JPanel panel ;
	private JPanel fileTransfer;
	private JPanel recordPanel ;
	private boolean isOpenRecordPane =false;
	private JTextPane receivePan;
	private ImageIcon errorIcon;
	private FileTranferPanel.MyFilePanel filePanel;
	private JScrollPane scrollPane;

	private static final DateFormat sdf = new SimpleDateFormat("HH:mm:ss");
	private File sendFile;
	/**
	 * Create the frame.
	 */


	public Chat(final User user) {
		super();
		errorIcon = new ImageIcon(Thread.currentThread()
				.getContextClassLoader().getResource("images/error.png"));
		this.user = user ;
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setTitle(user.getNickName());
		setBounds(100, 100, 544, 514);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContent(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));

		panel = new JPanel();
		contentPane.add(panel, BorderLayout.CENTER);
		panel.setLayout(new BorderLayout(0, 0));

		JPanel headPanel = new JPanel();
		headPanel.setBackground(Color.WHITE);
		headPanel.setBorder(UIManager.getBorder("FormattedTextField.border"));
		panel.add(headPanel, BorderLayout.NORTH);
		headPanel.setLayout(new BorderLayout(0, 0));

		JLabel head = new JLabel("");
		head.setIcon(new ImageIcon(Thread.currentThread()
				.getContextClassLoader().getResource(user.getImagePath())));
		headPanel.add(head, BorderLayout.WEST);

		JPanel panel_2 = new JPanel();
		headPanel.add(panel_2, BorderLayout.CENTER);
		panel_2.setLayout(new BorderLayout(0, 0));

		JLabel nickname = new JLabel(user.getNickName());
		nickname.setBackground(Color.WHITE);
		nickname.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		panel_2.add(nickname, BorderLayout.NORTH);

		JPanel sendFilePanel = new JPanel();
		sendFilePanel.setBackground(Color.WHITE);
		panel_2.add(sendFilePanel, BorderLayout.SOUTH);
		sendFilePanel.setLayout(new BorderLayout(0, 0));

		JButton sendFile = new JButton("");

		sendFile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser chooser = new JFileChooser() ;
				int result = chooser.showOpenDialog(null) ;
				if(result == JFileChooser.APPROVE_OPTION) {
					File file = chooser.getSelectedFile() ;
					addFileSendPanel(file, file.getName(),
							String.valueOf(file.length()), false);
				}

			}
		});
		sendFile.setToolTipText("发送文件");
		sendFile.setOpaque(false);
		sendFile.setBackground(new Color(2, 2, 2));
		sendFile.setIcon(new ImageIcon(Thread.currentThread()
				.getContextClassLoader().getResource("images/sendfile.jpg")));
		sendFile.setBorder(new EmptyBorder(new Insets(0, 0, 0, 0)));
		sendFilePanel.add(sendFile, BorderLayout.WEST);


		JPanel coldcasepanel = new JPanel();
		panel_2.add(coldcasepanel, BorderLayout.CENTER);
		coldcasepanel.setLayout(new BorderLayout(0, 0));

		JLabel coldCase = new JLabel(user.getPersonNote());
		coldCase.setBackground(Color.WHITE);
		coldCase.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		coldcasepanel.add(coldCase, BorderLayout.CENTER);

		JPanel content = new JPanel();
		content.setBackground(Color.WHITE);
		panel.add(content, BorderLayout.CENTER);
		content.setLayout(new BorderLayout(0, 0));

		JSplitPane splitPane = new JSplitPane();
		splitPane.setBorder(null);
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		content.add(splitPane, BorderLayout.CENTER);
		
		splitPane.setBorder(null); // 删除缺省边界
		splitPane.setOneTouchExpandable(false);
		splitPane.setOpaque(false);
		splitPane.setResizeWeight(0.7D);
		splitPane.setDividerSize(1);//设置分隔条大小

		JPanel northPanel = new JPanel();
		splitPane.setRightComponent(northPanel);
		northPanel.setLayout(new BorderLayout(0, 0));

		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		northPanel.add(scrollPane_1, BorderLayout.CENTER);

		final JEditorPane sendPan = new JEditorPane();
		sendPan.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		sendPan.setMargin(new Insets(0, 0, 0, 0));
		scrollPane_1.setViewportView(sendPan);

		JPanel toolPan = new JPanel();
		northPanel.add(toolPan, BorderLayout.NORTH);
		toolPan.setLayout(new BorderLayout(0, 0));

		// 查看聊天记录
		JButton record = new JButton("聊天记录");
		record.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(isOpenRecordPane){
					panel.remove(recordPanel) ;
					setBounds(100, 100, 544, 514);
					panel.add(showPanel, BorderLayout.EAST) ;
					isOpenRecordPane = false ;
				}else{
					recordPanel = new JPanel() ;
					panel.remove(showPanel) ;
					setBounds(100, 100, 750, 514);
					addRecordPanel() ;
					panel.add(recordPanel, BorderLayout.EAST);
					isOpenRecordPane = true ;
				}
			}
		});
		record.setIcon(new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("images/record.jpg")));
		record.setMargin(new Insets(1, 4, 1, 4));
		record.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		toolPan.add(record, BorderLayout.EAST);

		JPanel buttonPan = new JPanel();
		northPanel.add(buttonPan, BorderLayout.SOUTH);
		buttonPan.setLayout(new BorderLayout(0, 0));

		JPanel rightPan = new JPanel();
		buttonPan.add(rightPan, BorderLayout.EAST);
		FlowLayout fl_rightPan = new FlowLayout(FlowLayout.RIGHT, 5, 0);
		rightPan.setLayout(fl_rightPan);

		JButton close = new JButton("关闭");
		close.setMargin(new Insets(1, 14, 1, 14));
		close.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});
		close.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		rightPan.add(close);

		scrollPane = new JScrollPane();
		scrollPane
		.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		splitPane.setLeftComponent(scrollPane);

		receivePan = new JTextPane();
		receivePan.setContentType("text/html");
		receivePan.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		receivePan.setPreferredSize(new Dimension(106, 210));
		receivePan.setEditable(false);
		scrollPane.setViewportView(receivePan);
		scrollPane.setAutoscrolls(true);

		// 发送消息事件
		JButton send = new JButton("发送");
		send.setMargin(new Insets(1, 14, 1, 14));
		send.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				SwingUtilities.invokeLater(new Runnable() {

					public void run()
					{
						String sendMessage = sendPan.getText();
						if (sendMessage != null && sendMessage.length() > 0) {
							User sendedUser = ClientContext.getLoginUser();
							insertHeader(receivePan, sendedUser.getNickName()
									+ "   " + sdf.format(new Date()));
							insertMessage(receivePan, sendMessage);
							ECNioClient client = ClientContext.getContext()
									.getClient();
							try {
								client.sendTextMessage(sendMessage,
										sendedUser.getUserCode(),
										new String[] { user.getUserCode() });
								sendPan.setText("");
							} catch (Exception e) {
								JOptionPane.showMessageDialog(getThis(),
										"发送消息错误，请检查网路连接", "发送消息错误",
										JOptionPane.ERROR_MESSAGE);
							}
						} else {
							JOptionPane.showMessageDialog(getThis(),
									"发送消息不能为空", "发送消息错误",
									JOptionPane.ERROR_MESSAGE);
						}

					}
				});
			}
		});
		send.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		rightPan.add(send);


		showPanel = new JPanel();
		showPanel.setBackground(Color.WHITE);
		showPanel.setBorder(UIManager.getBorder("FormattedTextField.border"));
		panel.add(showPanel, BorderLayout.EAST);
		showPanel.setLayout(new BorderLayout(0, 0));

		JLabel friendShow = new JLabel("");
		friendShow.setIcon(new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("images/app.jpg")));
		showPanel.add(friendShow, BorderLayout.NORTH);

		JLabel myShow = new JLabel("");
		myShow.setIcon(new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("images/myapp.jpg")));
		showPanel.add(myShow, BorderLayout.SOUTH);
	}

	/**
	 * 创建文件发送面板
	 * 
	 * @param fileName
	 * @param icon
	 * @param fileSize
	 */
	public void addFileSendPanel(final File file, String fileName,
			final String fileSize,
			final boolean isReceiveSide) {
		panel.remove(showPanel);
		setBounds(100, 100, 680, 514);
		fileTransfer = new JPanel();
		fileTransfer.setLayout(new BorderLayout());
		filePanel = FileTranferPanel.newPanel(
				file, fileName,
				fileSize,
				isReceiveSide);
		filePanel.setOwner(this);
		fileTransfer.add(filePanel, BorderLayout.CENTER);
		panel.add(fileTransfer, BorderLayout.EAST);
		if (!isReceiveSide) {
			sendFile = file;
			ECPacket packet = new ECPacket();
			packet.setMessageType(ECMessageType.FILE_TRANSFER_INFO.name());
			String fileType = fileName.substring(fileName.lastIndexOf("."));
			packet.addParam("fileName",
					fileName.substring(0, fileName.lastIndexOf(".")));
			packet.addParam("fileType", fileType);
			packet.addParam("fileSize", fileSize);
			packet.setFrom(ClientContext.getLoginUser().getUserCode());
			packet.setTo(user.getUserCode());
			try {
				ClientContext.getContext().getClient().sendMessage(packet);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			file.delete();
			this.toFront();
			contentPane.updateUI();
		}

	}

	public void addFileReceivePanel(String fileName, String fileSize,
			String fileType) {
		try {
			File tempDir = new File(ClientContext.getValue("temp-dir", String.class)) ;
			if(!tempDir.exists()) {
				tempDir.mkdirs() ;
			}
			File file = File.createTempFile(fileName, fileType,tempDir );
			addFileSendPanel(file, fileName, fileSize, true);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建聊天记录面板
	 */
	public void addRecordPanel() {

		recordPanel.setBorder(UIManager.getBorder("FormattedTextField.border"));

		recordPanel.setLayout(new BorderLayout(0, 0));

		JPanel recordPane = new JPanel();
		recordPanel.add(recordPane, BorderLayout.CENTER);

		JLabel recordTitle = new JLabel("消息记录");
		recordTitle.setFont(new Font("微软雅黑", Font.PLAIN, 13));

		JButton closeRecord = new JButton("");
		closeRecord.setMargin(new Insets(2, 9, 2, 10));
		closeRecord.setIcon(new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("images/close.jpg")));
		closeRecord.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				closeReportPane() ;
			}
		}) ;

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) ;
		GroupLayout gl_recordPane = new GroupLayout(recordPane);
		gl_recordPane.setHorizontalGroup(
				gl_recordPane.createParallelGroup(Alignment.TRAILING)
				.addGroup(Alignment.LEADING, gl_recordPane.createSequentialGroup()
						.addContainerGap()
						.addComponent(recordTitle, GroupLayout.PREFERRED_SIZE, 62, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(ComponentPlacement.RELATED, 235, Short.MAX_VALUE)
						.addComponent(closeRecord, GroupLayout.PREFERRED_SIZE, 18, GroupLayout.PREFERRED_SIZE))
						.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)
				);
		gl_recordPane.setVerticalGroup(
				gl_recordPane.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_recordPane.createSequentialGroup()
						.addGap(4)
						.addGroup(gl_recordPane.createParallelGroup(Alignment.LEADING)
								.addComponent(recordTitle, GroupLayout.PREFERRED_SIZE, 17, GroupLayout.PREFERRED_SIZE)
								.addComponent(closeRecord))
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE))
				);

		JEditorPane report = new JEditorPane();
		report.setEditable(false);
		report.setContentType("text/html");
		String recordFilePath = ClientContext.getValue("message-record-save-path", String.class) ;
		Map<String,String> record = FileUtil.readRecord(MessageFormat.format(recordFilePath, getUser().getUserCode())) ;
		if(record!=null) {
			SimpleAttributeSet attrSet = new SimpleAttributeSet();
			StyleConstants.setFontFamily(attrSet, "微软雅黑");
			StyleConstants.setForeground(attrSet, Color.RED);
			StyleConstants.setFontSize(attrSet, 14);
			for(Iterator<String> keyIter = record.keySet().iterator();keyIter.hasNext();) {
				String key = keyIter.next() ;
				insert(report,String.format("-----------%s------------", key),attrSet);
				insertMessage(report, record.get(key)) ;
			}
		}
		scrollPane.setViewportView(report);
		recordPane.setLayout(gl_recordPane);
	}

	protected String getMessageRecord(){
		int len = receivePan.getDocument().getLength();
		try {
			return receivePan.getDocument().getText(0, len) ;
		} catch (BadLocationException e) {
		}
		return "" ;
	}
	
	@Override
	public void dispose() {
		super.dispose();
		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				String recordFilePath = ClientContext.getValue("message-record-save-path", String.class) ;
				if(recordFilePath != null) {
					FileUtil.writeMessage(MessageFormat.format(recordFilePath, getUser().getUserCode()), getMessageRecord());
				}
			}
		});
		ClientContext.removeKey(user.getUserCode());
	}

	public void closeFileSendPane(){
		setBounds(100, 100, 544, 514);
		panel.remove(fileTransfer);
		panel.add(showPanel, BorderLayout.EAST) ;
		contentPane.updateUI();
	}

	public void closeReportPane(){
		isOpenRecordPane = false ;
		setBounds(100, 100, 544, 514);
		panel.remove(recordPanel) ;
		panel.add(showPanel, BorderLayout.EAST) ;
	}

	public JFrame getThis() {
		return this;
	}

	private void insertHeader(JEditorPane editorPane, String str) {
		SimpleAttributeSet attrSet = new SimpleAttributeSet();
		StyleConstants.setFontFamily(attrSet, "微软雅黑");
		StyleConstants.setForeground(attrSet, Color.BLUE);
		insert(editorPane, str, attrSet);
	}

	private void insertMessage(JEditorPane editorPane, String str) {
		SimpleAttributeSet attrSet = new SimpleAttributeSet();
		StyleConstants.setFontFamily(attrSet, "微软雅黑");
		StyleConstants.setForeground(attrSet, Color.BLACK);
		insert(editorPane, str, attrSet);
	}

	private void insert(JEditorPane editorPane, String str, AttributeSet asst) {
		int lenth = editorPane.getDocument().getLength();
		try {
			editorPane.getDocument().insertString(lenth, str + "\n", asst);
			editorPane.setCaretPosition(editorPane.getDocument().getLength());
			contentPane.updateUI();
		} catch (BadLocationException e) {
			//
		} catch (Exception e) {
			// no ops
		}
	}

	public void insertOtherUserHeader(String nickName) {
		SimpleAttributeSet attrSet = new SimpleAttributeSet();
		StyleConstants.setFontFamily(attrSet, "微软雅黑");
		StyleConstants.setForeground(attrSet, Color.GREEN);
		insert(this.receivePan, nickName + "   " + sdf.format(new Date()),
				attrSet);
	}

	public void insertRecvMessae(String message) {
		insertMessage(this.receivePan, message);
	}

	public void insertErrorMessage(String message) {
		insertIconMessage(errorIcon, message);
	}

	public void insertSuccessMessage(String message) {
		ImageIcon succes = new ImageIcon(Thread.currentThread()
				.getContextClassLoader().getResource("images/accept.png"));
		insertIconMessage(succes, message);
	}

	protected void insertIconMessage(ImageIcon icon, String message) {

		int len = receivePan.getDocument().getLength();
		receivePan.setCaretPosition(len);
		JLabel label = new JLabel(icon);
		label.setText(message);
		label.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		label.setForeground(Color.RED);
		label.setBorder(new EmptyBorder(new Insets(1, 0, 1, 0)));
		receivePan.insertComponent(label);
		len = receivePan.getDocument().getLength();
		try {
			receivePan.getDocument().insertString(len, "\n", null);
			receivePan.setCaretPosition(receivePan.getDocument().getLength());
			//contentPane.repaint();
		} catch (BadLocationException e) {
			// no ops
		} catch (Exception e) {
			// no ops
		}

	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public File getSendFile() {
		return sendFile;
	}

	public void setSendFile(File sendFile) {
		this.sendFile = sendFile;
	}

	public void startFileTransfer(final String ip, final String port) {
		SwingUtilities.invokeLater(new Runnable() {
			
			public void run() {
				FileTransferSocketClient fclient = null;
				fclient = FileTransferSocketClient.newInstance(Integer.parseInt(port),
						ip);
				ClientContext.putValue("file-" + getUser().getUserCode(), fclient);
				fclient.setCallBack(new FileTransferCallBack() {
					public void callBack(final Object args) {
						
								if (args.getClass().isAssignableFrom(String.class)) {
									SwingUtilities.invokeLater(new Runnable() {
										
										public void run() {
											if (args.toString().equals("end")) {
												Object obj = ClientContext.removeKey("file-"
														+ getUser().getUserCode());
												if (obj != null) {
													((FileTransferSocketClient) obj).shutdown();
												}
												closeFileSendPane();
												insertSuccessMessage("文件发送成功");
											}
										}
									});
								} else {
									if (filePanel != null) {
										System.out.println(args);
										filePanel.updateProperties(((Long) args).longValue());
									}
								}
								
							}
						});
				fclient.setFile(getSendFile());
				new Thread(fclient).start();
			}
		});
	}

}
